// p5 ES5中的类、静态方法、继承

function Person(name = '小雨点') {
  this.name = name;
  this.age = 12;
  this.run = function () {
    console.log(this.name, '在运动。');
  };
}

/**
 * 类的静态属性和方法，只能通过 类名 来访问，不能通过实例化来访问。
 */
Person.Version = 'v1.0.0';
Person.printVersion = function () {
  console.log('当前版本：', Person.Version);
};

/**
 * 1. 多个实例共享，原型链的属性和方法
 * 2. 原型链属性和方法，只能通过 实例对象 来访问。
 * 3. 更改属性和方法会影响所有的对象
 */
Person.prototype.Author = 'ChenYong';
Person.prototype.printAuthor = function () {
  console.log('Author：', this.Author);
};

let p = new Person();

// p.printVersion(); // 报错
Person.printVersion(); // 正确

p.run(); // 实例访问
p.printAuthor();
Person.prototype.Author = 'ChenYong:xxmi';

let p1 = new Person();
p1.printAuthor();
p.printAuthor();

console.log('------------类的继承 原型链+对象冒充----------------------------');
/**
 * 类的继承 原型链+对象冒充
 */
console.log('------------对象冒充继承---------------------------------------');

/**
 * 1. 对象冒充
 * 优点：
 *     1. 对象冒充形式的继承，只能继承实例属性和方法。
 *     2. 可以给父类传递参数
 * 缺点：
 *     1. 不能继承类的：静态属性和方法、原型链
 */
function Web(name) {
  Person.call(this, name); // 对象冒充
}

let web = new Web('小雨点：很可爱');
web.run(); // 正确
//  web.printAuthor(); // 报错
// Web.printVersion(); // 报错

console.log('------------原型链继承-----------------------------------------');

/**
 * ２. 原型链继承
 * 总结：类的实例属性和方法、原型链的属性和方法
 * 缺点：
 *      1.不能继承类的：静态属性和方法
 *      2.不能给父类传递参数
 */
function China() {
}

China.prototype = new Person();

let c = new China();
c.run(); //正确
// c.printAuthor(); // 正确
// China.printVersion(); // 报错


console.log('------------原型链 + 对象组合形式的继承-------------------------');

/**
 * 优点：
 *      1. 可以继承：实例属性和方法、原型链的属性和方法
 *      2. 可以给父类传递参数
 * 缺点：
 *      1. 不能继承类的：静态属性和方法
 */
function Animal(name) {
  Person.call(this, name); // 对象冒充
}

Animal.prototype = Person.prototype;

let a = new Animal('哎呦喂哈');
a.run(); // 正确
a.printAuthor(); // 正确
// Animal.printVersion(); // 报错

/**
 * 总结：
 * 1. ES5 类的继承还是通过：原型链 + 对象组合形式的继承最好
 * 2. 不能继承类型静态属性和方法，且不必要（直接通过类名调用即可）
 */
